﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
using Microsoft.Phone.Reactive;


namespace APIMap
{
    public partial class MainPage : PhoneApplicationPage
    {
        GeoCoordinateWatcher gcw;
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (gcw == null)
                gcw = new GeoCoordinateWatcher();

            gcw.Start();

            ShowGeoLocation();
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);

            if (gcw != null)
                gcw.Stop();
        }

        //public void ShowGeoLocation()
        //{
        //    var statusChanges = from statusChanged in gcw.GetStatusChangedEventStream()
        //                        where statusChanged.Status == GeoPositionStatus.Ready
        //                        select statusChanged;

        //    var positionChanges = from s in statusChanges
        //                          from position in gcw.GetPositionChangedEventStream()
        //                          select position.Position;

        //    var positions = from position in positionChanges
        //                    where position.Location.HorizontalAccuracy <= 100
        //                    select position;

        //    positions.Take(1).Subscribe(firstLocationFix =>
        //    {
        //        textBlock1.Text = string.Format("{0},{1}"
        //                               , firstLocationFix.Location.Latitude
        //                               , firstLocationFix.Location.Longitude
        //                               );
        //    }
        //    );
        //}
        //==================================================================================
        public void ShowGeoLocation()
        {
            var statusChanges = from statusChanged in gcw.GetStatusChangedEventStream()
                                where statusChanged.Status == GeoPositionStatus.Ready
                                select statusChanged;

            var positionChanges = from s in statusChanges
                                  from position in gcw.GetPositionChangedEventStream()
                                  select position.Position;

            var positions = from position in positionChanges
                            where position.Location.HorizontalAccuracy <= 1000
                            select position;

            positions.Scan(new
            {
                i = 0
                            ,
                p = default(GeoPosition<GeoCoordinate>)
            },
                           (a, e) => new
                           {
                               i = a.i + 1
                                     ,
                               p = e
                           }
                          ).Subscribe(e =>
                          {
                              textBlock1.Text = string.Format("{0}:{1},{2}@{3}"
                                                                                     , e.i
                                                                                     , e.p.Location.Latitude
                                                                                     , e.p.Location.Longitude
                                                                                     , e.p.Location.HorizontalAccuracy
                                                                                     );
                          }
             );
        }
        //==================================================================================
    }
    public static class Helpers
    {
        public static IObservable<GeoPositionStatusChangedEventArgs> GetStatusChangedEventStream(this GeoCoordinateWatcher watcher)
        {
            return Observable.Create<GeoPositionStatusChangedEventArgs>(observer =>
            {
                EventHandler<GeoPositionStatusChangedEventArgs> handler = (s, e) =>
                {
                    observer.OnNext(e);
                };
                watcher.StatusChanged += handler;
                return () => { watcher.StatusChanged -= handler; };
            }
            );
        }

        public static IObservable<GeoPositionChangedEventArgs<GeoCoordinate>> GetPositionChangedEventStream(this GeoCoordinateWatcher watcher)
        {
            return Observable.Create<GeoPositionChangedEventArgs<GeoCoordinate>>(observable =>
            {
                EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>> handler = (s, e) =>
                {
                    observable.OnNext(e);
                };
                watcher.PositionChanged += handler;
                return () => { watcher.PositionChanged -= handler; };
            }
            );
        }
    }

}